package com.bkhech.netty.httpwebsocket.server;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.*;
import java.util.stream.Collectors;

/**
 * UserChannelCache
 *
 * @author guowm
 * @date 2024-11-11
 */
public class UserChannelCache {
    // 用于多端同时接收消息，允许一个账号多个平台在线，ipad，ios，Mac
    // key:userId  value:用户的多个channel
    private static final Map<String, List<Channel>> multiSession = new HashMap<>(32);

    // key:客户端长id  value: userId
    private static final Map<String, String> userChannelIdMap = new HashMap<>(32);

    public static void putChannelOfUser(String channelId, String userId) {
        userChannelIdMap.put(channelId, userId);
    }

    public static String getUserIdByChannelId(String channelId) {
        return userChannelIdMap.get(channelId);
    }

    public static void putMultiChannels(String userId, Channel channel) {
        List<Channel> channelList = getMultiChannels(userId);
        if (channelList == null) {
            channelList = new ArrayList<>();
        }
        channelList.add(channel);
        multiSession.put(userId, channelList);
    }

    public static void removeUselessChannels(String userId, String channelId) {
        List<Channel> channelList = getMultiChannels(userId);
        if (CollUtil.isEmpty(channelList)) {
            return;
        }

        channelList.removeIf(c -> Objects.equals(channelId, c.id().asLongText()));
        // 重新覆盖
        multiSession.put(userId, channelList);
    }

    public static List<Channel> getMultiChannels(String userId) {
        return multiSession.get(userId);
    }

    public static List<Channel> getMyOtherChannel(String userId, String channelId) {
        List<Channel> multiChannels = getMultiChannels(userId);
        if (CollUtil.isEmpty(multiChannels)) {
            return new ArrayList<>();
        }

        return multiChannels.stream()
                .filter(c -> !StrUtil.isBlank(channelId) && !channelId.equals(c.id().asLongText()))
                .collect(Collectors.toList());
    }

    public static void sendToTarget(List<Channel> receiverChannels, String dataContent) {
        final ChannelGroup channelGroup = ClientChannelGroup.getInstance();
        if (receiverChannels == null) {
            return;
        }

        for (Channel c : receiverChannels) {
            Channel findChannel = channelGroup.find(c.id());
            if (findChannel != null) {
                findChannel.writeAndFlush(new TextWebSocketFrame(dataContent));
            }
        }
    }
}
